# -*- coding: utf-8 -*-

import logging

from odoo import api, fields, models, _
from odoo.exceptions import ValidationError

from datetime import datetime

_logger = logging.getLogger(__name__)

STATE = [('draft', 'Draft'), ('confirm', 'Confirm'), ('done', 'Done')]


class StockTaking(models.Model):
    _name = 'stock.taking'
    _description = 'stock-taking'
    _inherit = ['mail.thread', 'mail.activity.mixin']

    name = fields.Char('name')
    state = fields.Selection(STATE, string='state', default='draft')
    note = fields.Text('note')
    confirm_date = fields.Datetime(string='confirm date', readonly=True)
    confirm_uid = fields.Many2one('res.users', string='confirm uid', readonly=True)
    done_date = fields.Datetime(string='done date', readonly=True)
    done_uid = fields.Many2one('res.users', string='done uid', readonly=True)
    line_ids = fields.One2many('stock.taking.line', 'parent_id', string='stock-taking line')

    def do_confirm(self):
        for item in self:
            taking_ids = self.env['stock.taking'].search([('state', '=', 'confirm'), ('id', '!=', item.id)])
            for line in item.line_ids:
                taking_line_id = self.env['stock.taking.line'].search([
                    ('parent_id', 'in', taking_ids.ids), ('product_id', '=', line.product_id.id),
                    ('lot_id', '=', line.lot_id.id), ('location_id', '=', line.location_id.id)
                ])
                if taking_line_id:
                    raise ValidationError(
                        _(
                            "Product '%s' with Lot '%s' and Location '%s' already exists" % (
                                line.product_id.name, line.lot_id.name, line.location_id.name
                            )
                        )
                    )
            self.env['stock.lot'].search([('id', 'in', list(item.line_ids.mapped('lot_id').ids))]).write({'is_lock': True})
        self.write({'state': 'confirm', 'confirm_date': datetime.now(), 'confirm_uid': self.env.user.id})

    def do_done(self):
        for item in self:
            for line in item.line_ids:
                quant_id = self.env['stock.quant'].search([
                    ('product_id', '=', line.product_id.id), ('lot_id', '=', line.lot_id.id),
                    ('location_id', '=', line.location_id.id)
                ])
                quant_id.inventory_quantity = line.qty_later
                quant_id.with_context({'is_stock_taking': True}).action_apply_inventory()
            self.env['stock.lot'].search([('id', 'in', list(item.line_ids.mapped('lot_id').ids))]).write({'is_lock': False})
        self.write({'state': 'done', 'done_date': datetime.now(), 'done_uid': self.env.user.id})

    def add_line_id(self):
        self.ensure_one()
        context = {
            'parent_model': self._name,
            'parent_id': self.id,
        }

        return {
            'type': 'ir.actions.act_window',
            'model': 'ir.actions.act_window',
            'name': _('ADD stock-taking line'),
            'res_model': 'stock.taking.details',
            'view_type': 'form',
            'view_mode': 'form',
            "view_id": False,
            'target': 'new',
            'context': context
        }


class StockTakingLine(models.Model):
    _name = 'stock.taking.line'
    _description = 'stock-taking line'

    parent_id = fields.Many2one('stock.taking', string='stock-taking', index=True, ondelete='cascade')
    state = fields.Selection(STATE, string='state', default='draft', compute='get_parent_state')
    product_id = fields.Many2one('product.product', string='product', readonly=True, required=True, index=True)
    lot_id = fields.Many2one('stock.lot', string='lot', readonly=True)
    location_id = fields.Many2one('stock.location', 'location', readonly=True)
    qty_before = fields.Float(string='Pre-count quantity', compute='get_qty_before', store=True)
    qty_later = fields.Float(string='Quantity after count', default=0)

    def get_parent_state(self):
        self.state = self.parent_id.state

    @api.depends('lot_id')
    def get_qty_before(self):
        qty_before = 0
        for item in self:
            if item.lot_id:
                lot_id = self.env['stock.lot'].sudo().search_read([('id', '=', item.lot_id.id)], fields=['product_qty'])
                if lot_id:
                    qty_before = lot_id[0]['product_qty']
            item.qty_before = qty_before


class StockTakingDetails(models.TransientModel):
    _name = 'stock.taking.details'
    _description = 'stock-taking details'

    product_id = fields.Many2one('product.product', string='product', required=True, index=True)
    start_time = fields.Datetime(string='start date')
    end_time = fields.Datetime(string='end date')
    query = fields.Boolean('query', required=True, default=False)
    line_ids = fields.One2many('stock.taking.details.line', 'parent_id', string='stock.taking.details.line')

    @api.onchange('query')
    def query_product(self):
        self.line_ids = False

        domain = [('product_id', '=', self.product_id.id)]
        if self.start_time:
            domain.append(('create_date', '>=', self.start_time))
        if self.end_time:
            domain.append(('create_date', '<=', self.end_time))

        location_id = self.env['stock.location'].search([('name', '=', 'Virtual Locations')])
        if location_id:
            domain.append(('location_id', 'not in', location_id.child_ids.ids))

        quant_ids = self.env['stock.quant'].search(domain)

        line_id = [{
            'lot_id': quant_id.lot_id.id,
            'location_id': quant_id.location_id.id,
            'qty_before': quant_id.available_quantity,
        } for quant_id in quant_ids]

        self.line_ids = [(0, 0, line) for line in line_id]

    def do_confirm(self):
        line_ids = []
        for line in self.line_ids:
            if not line.is_select:
                continue
            line_ids.append((0, 0, {
                'product_id': self.product_id.id,
                'lot_id': line.lot_id.id,
                'location_id': line.location_id.id,
            }))
        model_name = self._context.get('parent_model', False)
        model_id = self._context.get('parent_id', False)
        taking_id = self.env[model_name].search([('id', '=', model_id)])
        taking_id.line_ids = line_ids


class StockTakingDetailsLine(models.TransientModel):
    _name = 'stock.taking.details.line'
    _description = 'stock-taking details line'

    parent_id = fields.Many2one('stock.taking.details', string='stock.taking.details', index=True, ondelete='cascade')
    is_select = fields.Boolean(string='is select', required=True, default=False)
    lot_id = fields.Many2one('stock.lot', string='lot', readonly=True)
    location_id = fields.Many2one('stock.location', 'location', readonly=True)
    qty_before = fields.Float(string='Pre-count quantity', readonly=True, default=0)
    qty_later = fields.Float(string='Quantity after count', default=0)
